﻿using System;
using Crm.Plugins.DuplicateChecker.Data;
using Crm.Plugins.DuplicateChecker.Domain;
using Microsoft.Crm.Sdk;

namespace Crm.Plugins.DuplicateChecker{
    /// <summary>
    /// 
    /// </summary>
    public sealed class DuplicateHandler : IDisposable{
        private readonly CrmConfiguration _crmConfiguration;
        private readonly CrmConfigurationRepository _crmConfigurationRepository;
        private readonly ICrmService _crmService;
        private readonly DynamicEntity _targetEntity;
        private readonly TargetEntityRepository _targetEntityRepository;
        private bool _disposed;

        /// <summary>
        /// Gets value of the Key Attribute.
        /// </summary>
        /// <value>The value corresponding to the Key Attribute/>.</value>
        public int EntityId { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="DuplicateHandler"/> class.
        /// </summary>
        /// <param name="crmService"></param>
        /// <param name="targetEntity"></param>
        /// <param name="schemaPrefix"></param>
        public DuplicateHandler(ICrmService crmService, DynamicEntity targetEntity, string schemaPrefix){
            _targetEntity = targetEntity;
            _crmService = crmService;

            // Initialize Data Sources
            _crmConfigurationRepository = new CrmConfigurationRepository(_crmService, schemaPrefix);
            _targetEntityRepository = new TargetEntityRepository(_crmService);

            // Initialize Component
            _crmConfiguration = _crmConfigurationRepository.Get(_targetEntity.Name);
            EntityId = getEntityId();
        }

        public void Dispose(){
            disposeObject(true);
            GC.SuppressFinalize(this);
        }

        private int getEntityId(){
            if (!_targetEntity.Properties.Contains(_crmConfiguration.KeyAttribute)){
                throw new InvalidOperationException(String.Format("The specified key attribute is invalid for this entity. Attribute:{0}",
                                                                  _crmConfiguration.KeyAttribute));
            }
            int entityId = ((CrmNumber) _targetEntity.Properties[_crmConfiguration.KeyAttribute]).Value;
            return entityId;
        }

        /// <summary>
        /// Finds the number of instances of this entity.
        /// </summary>
        /// <returns>A count of instances in CRM with this <c>EntityId</c>.</returns>
        public int Find(){
            int entityCount = _targetEntityRepository.GetCount(_targetEntity.Name, _crmConfiguration.KeyAttribute, EntityId);
            return entityCount;
        }

        ~DuplicateHandler(){
            disposeObject(false);
        }

        private void disposeObject(bool disposing){
            if (_disposed){
                return;
            }
            if (disposing){
                if (_crmService != null){
                    _crmService.Dispose();
                }
            }
            _disposed = true;
        }
    }
}